<template>
  <div class="add-model" v-loading="modelLoading" element-loading-text="模型生成中，请稍等...">
    <div class="model-header">
      <div class="mh-left">
        <el-select v-model="taskType" placeholder="请选择任务类型" style="width: 200px">
          <el-option v-for="item in sys_task_type" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-input size="large" v-model="modelName" placeholder="任务名称" clearable style="width: 220px;margin: 12px;" />
        <el-input v-show="uploadTypeFlag" size="large" v-model="modelCode" placeholder="任务编号" clearable
          style="width: 220px;" />
      </div>
      <div class="mh-right">
        <label>上传方式：</label>
        <el-radio-group v-model="uploadTypeFlag">
          <el-radio-button :label="true">图片</el-radio-button>
          <el-radio-button :label="false">模型</el-radio-button>
        </el-radio-group>
      </div>
    </div>
    <div class="model-content" v-show="uploadTypeFlag">
      <el-upload @change="handleFileChange" :limit="100" :show-file-list="false" drag action="#" multiple
        :auto-upload="false">
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          拖拽文件或<em>点击上传</em><br />
          <div style="color: #999;font-size: 12px; margin-top: 5px">上传的照片总数不超过100张，建议上传10张以上照片</div>
        </div>
      </el-upload>
      <div v-if="fileList.length > 0" style="margin-top: 12px;">共 {{ viewPic.length }} 张照片</div>
      <div class="model-content-list" v-loading="picLoading">
        <div class="model-content-list-item" v-for="(item, index) in viewPic" :key="item.uid">
          <div class="delete-icon" @click="handleRemove(item)">
            <el-icon color="red">
              <RemoveFilled />
            </el-icon>
          </div>
          <img :src="item.url" :alt="item.name">
          <el-icon class="success-icon" color="#67C23A" v-if="index <= successCount && successCount > 0">
            <SuccessFilled />
          </el-icon>
          <el-tooltip class="box-item" effect="dark" :content="item.name" placement="top-start">
            <div class="name">{{ item.name }}</div>
          </el-tooltip>
        </div>
      </div>
    </div>
    <div class="model-content2" v-show="!uploadTypeFlag" v-loading.fullscreen="isLoading_model"
      :element-loading-text="isLoading_model_text">
      <div v-show="zipFileList.length" style="width: 30%;">
        <el-upload v-model:file-list="zipFileList" :limit="1" action="#" :auto-upload="false" accept=".zip">
          <div></div>
        </el-upload>
      </div>
      <div v-show="!zipFileList.length">
        <el-upload v-model:file-list="zipFileList" :limit="1" drag action="#" :auto-upload="false" accept=".zip">
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">
            拖拽文件或<em>点击上传</em><br />
            <div style="color: #999;font-size: 12px; margin-top: 5px">请直接上传模型压缩文件</div>
          </div>
        </el-upload>
      </div>
    </div>
    <div class="model-footer" v-show="uploadTypeFlag">
      <div class="progress-info" v-if="loading">
        <el-progress :text-inside="true" :stroke-width="20"
          :percentage="(+(successCount / fileList.length * 100).toFixed(2)) || 0" style="width: 300px;" />
        <div class="progress-text">已上传: {{ successCount }}/{{ fileList.length }}</div>
      </div>
      <div class="button-group">
        <el-button size="large" @click="handleCancel">取消</el-button>
        <el-button v-if="!uploading" type="primary" size="large" @click="handleSave" :loading="loading">上传</el-button>
        <el-button v-else type="primary" size="large" @click="handleDispose">开始处理</el-button>
      </div>
    </div>
    <div class="model-footer" v-show="!uploadTypeFlag">
      <div class="progress-info">
      </div>
      <div class="button-group">
        <el-button size="large" @click="handleCancel">取消</el-button>
        <el-button type="primary" size="large" @click="handleUploadModel">上传模型</el-button>
      </div>
    </div>
  </div>
</template>

<script setup name="AddModel">
import { ref } from 'vue'
import { compressFiles } from '@/utils/ruoyi';
const modelName = ref('');
const modelCode = ref('');
const taskType = ref('2');

const uploadTypeFlag = ref(true);
const isLoading_model = ref(false);
const isLoading_model_text = ref('处理文件中，中途请勿退出和刷新页面。处理时间大概几分钟，请耐心等待...');
const zipFileList = ref([]);

const fileList = ref([]);
const successCount = ref(0); // 成功上传的文件索引用户显示进度条
const modelLoading = ref(false);
const loading = ref(false);
const uploading = ref(false); // 是否上传完成
const { proxy } = getCurrentInstance();
const successFile = ref([]); // 成功上传的文件返回的数据
import { uploadModelPictrue, startModelTask, uploadDronePanorama } from '@/api/model';
const { sys_task_type } = proxy.useDict("sys_task_type");
const viewPic = ref([]); // 预览图片
const picLoading = ref(false);
// 处理文件变化
const handleFileChange = async (file) => {
  picLoading.value = true;
  const compressedFile = await compressFiles(file?.raw);
  compressedFile.url = URL.createObjectURL(compressedFile);
  viewPic.value.push(compressedFile)
  viewPic.value = viewPic.value.map(i => {
    return {
      ...i,
      name: i.name.split('_').at(-1)
    }
  })
  fileList.value.push(file);
  picLoading.value = false;
};
const handleRemove = (file) => {
  fileList.value = fileList.value.filter(item => item.uid !== file.uid);
}
// 取消
const handleCancel = () => {
  // 关闭当前tabs
  const obj = { path: "/modelToTask" };
  proxy.$tab.closeOpenPage(obj);
};
// 保存
const handleSave = () => {
  if (!modelName.value) return proxy.$modal.msgError("任务名称不能为空");
  if (!modelCode.value) return proxy.$modal.msgError("任务编号不能为空");
  if (fileList.value.length === 0) return proxy.$modal.msgError("请先选择照片");
  loading.value = true;
  const batchSize = 5; // 每批次处理5个文件
  const files = fileList.value;
  async function processBatch(startIndex) {
    const batch = files.slice(startIndex, startIndex + batchSize);
    const promises = batch.map(file => {
      const formData = new FormData();
      formData.append("files", file?.raw || file);
      formData.append("taskName", modelName.value);
      formData.append("bizId", modelCode.value);
      return uploadModelPictrue(formData);
    });
    try {
      const { data } = await Promise.race(promises);
      successFile.value = data;
      successCount.value += batch.length;
      if (startIndex + batchSize < files.length) {
        // 继续处理下一批
        await processBatch(startIndex + batchSize);
      } else {
        uploading.value = true;
        // 所有批次处理完成
        proxy.$modal.msgSuccess("上传成功");
        loading.value = false;
      }
    } catch (error) {
      loading.value = false;
      proxy.$modal.msgError(error.message);
    }
  }
  // 开始第一批处理
  processBatch(0);
}
// 开始处理生成模型
const handleDispose = () => {
  modelLoading.value = true;
  const formData = new FormData();
  formData.append("inputMinoDirectory", successFile.value);
  formData.append("taskName", modelName.value);
  formData.append("taskType", taskType.value);
  formData.append("bizId", modelCode.value);
  startModelTask(formData).then(res => {
    proxy.$modal.msgSuccess("模型生成成功");
    modelLoading.value = false;
    handleCancel();
  }).catch(err => {
    modelLoading.value = false;
    proxy.$modal.msgError(err.message);
  })
}

// 上传模型
const handleUploadModel = async () => {
  try {
    isLoading_model.value = true;

    // 拦截
    const fileZip = zipFileList.value[0]?.raw;
    if (!fileZip) {
      throw new Error("请上传模型压缩文件！");
    }

    let query = [];
    if (modelName.value) { query.push('taskName=' + modelName.value); }
    if (taskType.value) { query.push('taskType=' + taskType.value); }
    query = query.join('&');

    const formData = new FormData();
    formData.append('fileZip', fileZip);

    let dropNum = 3;
    await uploadDronePanorama(query, formData, (progressEvent) => {
      const percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      if (percentCompleted === 100) {
        let dropStr = new Array(dropNum).fill('.').join('');
        if (dropNum === 3) dropNum = 1;
        else dropNum++;

        isLoading_model_text.value = `文件上传成功。\n处理文件中，中途请勿退出和刷新页面。\n处理时间大概几分钟，请耐心等待${dropStr}`;
      } else {
        isLoading_model_text.value = `文件上传进度: ${percentCompleted}%`;
      }
    });
    handleCancel();//退出
  } catch (err) {
    proxy.$modal.msgError(err.message);
  } finally {
    isLoading_model.value = false;
  }
}
</script>

<style lang="scss" scoped>
.add-model {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: calc(100vh - 90px);

  .model-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 24px;
    border-bottom: 1px solid #e6e6e6;

    .mh-right {
      display: flex;
      align-items: center;

      &>label {
        font-size: 14px;
        color: #333;
        font-weight: normal
      }
    }
  }

  .model-content {
    padding: 24px;
    flex: 1;
    position: relative;

    .model-content-list {
      display: flex;
      flex-wrap: wrap;
      // justify-content: space-around;
      align-items: start;
      flex-wrap: wrap;
      gap: 20px;
      height: 43vh;
      overflow: auto;
      margin-top: 12px;
      padding-left: 40px;

      .model-content-list-item {
        width: 160px;
        height: 160px;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;

        &:hover {
          background-color: #f0f0f0;
          cursor: pointer;

          .delete-icon {
            display: block;
          }
        }

        .delete-icon {
          position: absolute;
          top: 0;
          right: 0;
          cursor: pointer;
          display: none;
        }

        img {
          width: 100px;
          height: 100px;
          object-fit: cover;
        }

        .name {
          margin-top: 5px;
          font-size: 14px;
          width: 100px;
          text-align: center;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
  }

  .model-content2 {
    padding: 24px;
    flex: 1;
    position: relative;
  }

  .model-footer {
    border-top: 1px solid #e6e6e6;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: relative;
    height: 80px;

    .progress-info {
      margin-left: 24px;
      margin-top: 24px;

      .progress-text {
        display: block;
        margin-bottom: 8px;
        color: #606266;
        font-size: 14px;
      }
    }

    .button-group {
      position: absolute;
      right: 12px;
    }
  }
}

.success-icon {
  position: absolute;
  bottom: 0px;
  right: 45%;
}
</style>
